package com.education.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.education.platform.common.ResultCode;
import com.education.platform.dto.DashboardOverviewDTO;
import com.education.platform.dto.OrderStatsDTO;
import com.education.platform.dto.UserTrendDTO;
import com.education.platform.entity.Statistics;
import com.education.platform.exception.BusinessException;
import com.education.platform.mapper.StatisticsMapper;
import com.education.platform.service.StatisticsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 统计服务实现类
 *
 * @author education-platform
 * @since 2024-09-27
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class StatisticsServiceImpl implements StatisticsService {

    private final StatisticsMapper statisticsMapper;

    @Override
    @Transactional
    public Long createStatistics(Statistics statistics) {
        statisticsMapper.insert(statistics);
        log.info("创建统计记录成功, 日期: {}, 类型: {}", statistics.getStatDate(), statistics.getStatType());
        return statistics.getId();
    }

    @Override
    @Transactional
    public void updateStatistics(Long id, Statistics statistics) {
        Statistics stat = getStatisticsById(id);
        
        stat.setStatValue(statistics.getStatValue());
        stat.setExtraData(statistics.getExtraData());
        
        statisticsMapper.updateById(stat);
        log.info("更新统计记录成功, ID: {}", id);
    }

    @Override
    @Transactional
    public void deleteStatistics(Long id) {
        statisticsMapper.deleteById(id);
        log.info("删除统计记录成功, ID: {}", id);
    }

    @Override
    public Statistics getStatisticsById(Long id) {
        Statistics statistics = statisticsMapper.selectById(id);
        if (statistics == null) {
            throw new BusinessException(ResultCode.NOT_FOUND);
        }
        return statistics;
    }

    @Override
    public Statistics getStatisticsByDateAndType(LocalDate statDate, String statType) {
        return statisticsMapper.selectByDateAndType(statDate, statType);
    }

    @Override
    public List<Statistics> getStatisticsByDateRange(String statType, LocalDate startDate, LocalDate endDate) {
        return statisticsMapper.selectByDateRange(statType, startDate, endDate);
    }

    @Override
    public Statistics getLatestStatistics(String statType) {
        return statisticsMapper.selectLatestByType(statType);
    }

    @Override
    @Transactional
    public void saveOrUpdateStatistics(LocalDate statDate, String statType, Long statValue, String extraData) {
        Statistics existing = getStatisticsByDateAndType(statDate, statType);
        
        if (existing != null) {
            // 更新
            existing.setStatValue(statValue);
            existing.setExtraData(extraData);
            statisticsMapper.updateById(existing);
            log.debug("更新统计: 日期={}, 类型={}, 值={}", statDate, statType, statValue);
        } else {
            // 创建
            Statistics statistics = new Statistics();
            statistics.setStatDate(statDate);
            statistics.setStatType(statType);
            statistics.setStatValue(statValue);
            statistics.setExtraData(extraData);
            statisticsMapper.insert(statistics);
            log.debug("创建统计: 日期={}, 类型={}, 值={}", statDate, statType, statValue);
        }
    }

    @Override
    public Long sumByTypeAndDateRange(String statType, LocalDate startDate, LocalDate endDate) {
        return statisticsMapper.sumByTypeAndDateRange(statType, startDate, endDate);
    }

    @Override
    @Transactional
    public void executeDailyStatistics() {
        LocalDate yesterday = LocalDate.now().minusDays(1);
        
        log.info("开始执行每日统计任务, 日期: {}", yesterday);
        
        try {
            statisticsUserData(yesterday);
            statisticsOrderData(yesterday);
            statisticsDemandData(yesterday);
            
            log.info("每日统计任务完成");
        } catch (Exception e) {
            log.error("每日统计任务执行失败", e);
            throw e;
        }
    }

    @Override
    @Transactional
    public void statisticsUserData(LocalDate statDate) {
        // TODO: 实现用户数据统计
        // 例如：新增用户数、活跃用户数等
        log.info("统计用户数据: {}", statDate);
    }

    @Override
    @Transactional
    public void statisticsOrderData(LocalDate statDate) {
        // TODO: 实现订单数据统计
        // 例如：订单数量、订单金额等
        log.info("统计订单数据: {}", statDate);
    }

    @Override
    @Transactional
    public void statisticsDemandData(LocalDate statDate) {
        // TODO: 实现需求数据统计
        // 例如：新增需求数、匹配成功数等
        log.info("统计需求数据: {}", statDate);
    }
    
    @Override
    public DashboardOverviewDTO getDashboardOverview() {
        DashboardOverviewDTO overview = new DashboardOverviewDTO();
        
        // 统计总用户数
        Long totalUsers = statisticsMapper.countTotalUsers();
        overview.setTotalUsers(totalUsers != null ? totalUsers : 0L);
        
        // 统计昨日用户数（用于计算增长率）
        LocalDate yesterday = LocalDate.now().minusDays(1);
        Long yesterdayNewUsers = statisticsMapper.countUserGrowthByDate(yesterday, null);
        overview.setUserGrowthRate(calculateGrowthRate(yesterdayNewUsers, totalUsers));
        
        // 统计总教员数
        Long totalTeachers = statisticsMapper.countTotalTeachers();
        overview.setTotalTeachers(totalTeachers != null ? totalTeachers : 0L);
        
        // 统计昨日新增教员数
        Long yesterdayNewTeachers = statisticsMapper.countUserGrowthByDate(yesterday, "TEACHER");
        overview.setTeacherGrowthRate(calculateGrowthRate(yesterdayNewTeachers, totalTeachers));
        
        // 统计总订单数
        Long totalOrders = statisticsMapper.countTotalOrders();
        overview.setTotalOrders(totalOrders != null ? totalOrders : 0L);
        
        // 统计昨日订单增长（这里简化处理，实际应该查询昨日新增订单数）
        overview.setOrderGrowthRate(BigDecimal.ZERO);
        
        // 统计今日收入
        BigDecimal todayIncome = statisticsMapper.sumTodayIncome();
        overview.setTodayIncome(todayIncome != null ? todayIncome : BigDecimal.ZERO);
        
        // 统计昨日收入
        BigDecimal yesterdayIncome = statisticsMapper.sumYesterdayIncome();
        overview.setIncomeGrowthRate(calculateGrowthRate(yesterdayIncome, todayIncome));
        
        return overview;
    }
    
    @Override
    public UserTrendDTO getUserTrend(Integer days) {
        if (days == null || days <= 0) {
            days = 7; // 默认7天
        }
        
        UserTrendDTO trend = new UserTrendDTO();
        List<String> dates = new ArrayList<>();
        List<Long> parentData = new ArrayList<>();
        List<Long> teacherData = new ArrayList<>();
        
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        
        // 获取最近N天的数据
        for (int i = days - 1; i >= 0; i--) {
            LocalDate date = LocalDate.now().minusDays(i);
            dates.add(date.format(formatter));
            
            // 查询该日期的家长新增数
            Long parentCount = statisticsMapper.countUserGrowthByDate(date, "PARENT");
            parentData.add(parentCount != null ? parentCount : 0L);
            
            // 查询该日期的教员新增数
            Long teacherCount = statisticsMapper.countUserGrowthByDate(date, "TEACHER");
            teacherData.add(teacherCount != null ? teacherCount : 0L);
        }
        
        trend.setDates(dates);
        trend.setParentData(parentData);
        trend.setTeacherData(teacherData);
        
        return trend;
    }
    
    @Override
    public OrderStatsDTO getOrderStats() {
        OrderStatsDTO stats = new OrderStatsDTO();
        List<OrderStatsDTO.StatusItem> items = new ArrayList<>();
        
        // 统计各状态的订单数量
        String[] statuses = {"PENDING", "ACCEPTED", "PAID", "CANCELLED"};
        String[] statusNames = {"待支付", "进行中", "已完成", "已取消"};
        
        for (int i = 0; i < statuses.length; i++) {
            OrderStatsDTO.StatusItem item = new OrderStatsDTO.StatusItem();
            item.setName(statusNames[i]);
            Long count = statisticsMapper.countOrdersByStatus(statuses[i]);
            item.setValue(count != null ? count : 0L);
            items.add(item);
        }
        
        stats.setStatusItems(items);
        return stats;
    }
    
    /**
     * 计算增长率
     */
    private BigDecimal calculateGrowthRate(Long yesterday, Long today) {
        if (yesterday == null || yesterday == 0) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal yesterdayVal = new BigDecimal(yesterday);
        BigDecimal todayVal = new BigDecimal(today != null ? today : 0);
        
        return todayVal.subtract(yesterdayVal)
                .divide(yesterdayVal, 4, RoundingMode.HALF_UP)
                .multiply(new BigDecimal(100));
    }
    
    /**
     * 计算增长率（BigDecimal版本）
     */
    private BigDecimal calculateGrowthRate(BigDecimal yesterday, BigDecimal today) {
        if (yesterday == null || yesterday.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal todayVal = today != null ? today : BigDecimal.ZERO;
        
        return todayVal.subtract(yesterday)
                .divide(yesterday, 4, RoundingMode.HALF_UP)
                .multiply(new BigDecimal(100));
    }
}

